package data.join.com.http;

import android.content.Context;
import android.text.TextUtils;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import data.join.com.database.bean.ImageDBPref;
import data.join.com.database.bean.VideoBean;
import data.join.com.database.bean.VideoDBPref;
import data.join.com.utils.MyDate;
import data.join.com.utils.MyLog;
import data.join.com.utils.QuickShPref;
import fi.iki.elonen.NanoHTTPD;

/**
 * Created by wenlong on 16-4-25.
 */
public class HttpServer extends NanoHTTPD {
    public static final String TAG = "HttpServer";

    public static final String MIME_JSON = "application/json";

    public final String API_URL_START = "/joinData";
    public final String API_GET_EVENT = "/getevent";
    public final String API_VIDEO_PATH = "/deviceinfo";
    public final String API_START_NAVI = "/startnavi";
    public final String API_SET_WIFI_INFO = "/setwifissidpwd";
    public final String API_WIFI_REFRSH = "/wifirefresh";
    public final String API_VIDEO_LIST = "/videolist";
    public final String API_DELETE_VIDEO = "/deletevideo";
    public final String car_DownloadEvent = "/car_DownladEvent";
    public final String API_VIDEO_INFO = "/videoinfo";
    public final String API_IMAGE_LIST = "/imagelist";
    public final String API_DELETE_IMAGE = "/deleteImage";
    public final String API_FAVICON_ICO = "/favicon.ico";

    private static HttpServer mInstance;

    public static final int ServerPort = 2016;

    private HttpServer() {
        super(ServerPort);
    }

    public static HttpServer getInstance(){
        if(mInstance == null){
            mInstance = new HttpServer();
        }
        return mInstance;
    }

    @Override
    public void start(){
        try {
            super.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Response serve(IHTTPSession session) {
        String url = session.getUri();
        MyLog.D(TAG,"url="+url);
        MyLog.D(TAG,""+session.getHeaders().toString());

        if(url.startsWith(API_FAVICON_ICO)){
            url = "/sdcard"+url;
        }

        File file = new File(url);

        //Log.d(TAG, Log.getStackTraceString(new Throwable()));

        if(url.startsWith(API_URL_START)) {
            return newFixedLengthResponse(Response.Status.OK, MIME_JSON, api(session));
        }else if(file.exists()){
                if (file.isDirectory()) {
                    return newFixedLengthResponse(Response.Status.OK, MIME_JSON, getDirFileListJson(file));
                }else {
                    try {
                        //getXML(session);
                        //MyLog.D(TAG,"Header="+session.getHeaders().toString());
                        InputStream fis = new FileInputStream(file);

                        String miniType = "*/*";
                        if(url.endsWith(".mp4")){
                            miniType = "video/mp4";
                        }else if(url.endsWith(".jpg")||url.endsWith(".jpeg")){
                            miniType = "image/jpeg";
                        }
                        String range = session.getHeaders().get("range");
                        MyLog.D(TAG,"range="+range);

                        Range headerRange;
                        if(range!=null) {
                            headerRange = getRange(range);
                        }else{
                            return newFixedLengthResponse(Response.Status.OK, miniType, fis, file.length());
                        }

                        long start = headerRange.getStart();
                        long end = headerRange.getEnd();
                        long length = 0;

                        if (start < 0) start = 0;
                        if (start > file.length()) start = file.length() - 1;
                        if (end > file.length()) end = file.length() - 1;

                        if (end < 0) {
                            end = file.length() - 1;
                        }

                        length = end - start + 1;
                        String bytes = String.format("bytes %d-%d/%d", start, end, file.length());
                        fis.skip(start);

                        String eTag = Integer.toHexString((file.getAbsolutePath()+file.lastModified()+file.length()).hashCode());

                        MyLog.D(TAG, "bytes=" + bytes);
                        MyLog.D(TAG, "start=" + start + ",end=" + end + ",length=" + length);

                        Response.IStatus resStatus = Response.Status.OK;
                        if(length<file.length()) {
                            resStatus = Response.Status.PARTIAL_CONTENT;
                        }

                        Response response = newFixedLengthResponse(resStatus, miniType, fis, length);
                        response.addHeader("Content-Range",bytes);
                        response.addHeader("ETag",eTag);
                        return response;
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return newFixedLengthResponse(Response.Status.OK, MIME_JSON, ""+e.toString());
                    }
                }
        }else if(file.exists() == false){
            return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_JSON,"file not exists");
        }else {
            return super.serve(session);
        }
    }

    private String getDirFileListJson(File dir){
        File[] list = dir.listFiles();
        List<Object> fileList = new ArrayList<>();
        if(list != null){
            for(File f:list){
                FileBean bean = new FileBean(f);
                fileList.add(bean);
            }
        }
        //JSONArray array = new JSONArray(fileList);

        Gson gson = new Gson();
        gson.toJson(fileList);

        return gson.toJson(fileList);
    }

    private String api(IHTTPSession session){
        String ret = "error api address!";
        String url = session.getUri();
        Map<String, String> reqBodyParams = new HashMap<String, String>();

        try {
            session.parseBody(reqBodyParams);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ResponseException e) {
            e.printStackTrace();
        }

        MyLog.D(TAG,"params="+session.getParms().toString());
        MyLog.D(TAG,"reqBodyParams="+reqBodyParams.toString());

        if(url.endsWith(API_GET_EVENT)){
            ret = getEventListJsonString(session);
        }else if(url.endsWith(API_VIDEO_PATH)){
            ret = getDeviceInfo(session);
        }else if(url.endsWith(API_START_NAVI)){
            ret = getstartNavi(session);
        }else if(url.endsWith(API_SET_WIFI_INFO)){
            ret = setWifiSsidPwd(session);
        }else if(url.endsWith(API_WIFI_REFRSH)){
            ret = setWifiRefresh(session);
        }else if(url.endsWith(API_VIDEO_LIST)){
            ret = getVideoListJsonString(session);
        }else if(url.endsWith(API_DELETE_VIDEO)){
            ret = deleteVideo(session,reqBodyParams);
        }else if(url.endsWith(car_DownloadEvent)){
            //refreshServerUrl();
            ret = car_DownloadEvent(session);
        }else if(url.endsWith(API_VIDEO_INFO)){
            ret = getVideoInfo(session);
        }else if(url.endsWith(API_IMAGE_LIST)){
            ret = imageList(session);
        }else if(url.endsWith(API_DELETE_IMAGE)){
            ret = deleteImage(session,reqBodyParams);
        }

        return ret;
    }

    private String deleteVideo(IHTTPSession session, Map<String, String> reqBodyParams){
        if(Method.POST.equals(session.getMethod())){
            String postData = reqBodyParams.get("postData");
            if(TextUtils.isEmpty(postData)){
                return getResultJson(2,"请求数据为空",null);
            }else {
                //VideoDelete videoDelete = JSON.parseObject(postData,VideoDelete.class);
                VideoDelete videoDelete = new Gson().fromJson(postData,VideoDelete.class);
                String devImei =  QuickShPref.getInstance().getString(QuickShPref.DeviceImei);
                if(videoDelete == null )
                    return getResultJson(2,"请求数据有误",null);
                else if(TextUtils.isEmpty(videoDelete.deviceImei) || !videoDelete.deviceImei.equals(devImei))
                    return getResultJson(3,"IMEI 错误",null);
                else if(videoDelete.start())
                    return getResultJson(0,"操作成功",null);
                else
                    return getResultJson(4,"删除失败",null);
            }
        }else{
            return getResultJson(1,"请求类型错误",null);
        }
    }

    private String deleteImage(IHTTPSession session, Map<String, String> reqBodyParams){
        if(Method.POST.equals(session.getMethod())){
            String postData = reqBodyParams.get("postData");
            if(TextUtils.isEmpty(postData)){
                return getResultJson(2,"请求数据为空",null);
            }else {
                //ImageDelete imageDelete = JSON.parseObject(postData,ImageDelete.class);
                ImageDelete imageDelete = new Gson().fromJson(postData,ImageDelete.class);
                String devImei =  QuickShPref.getInstance().getString(QuickShPref.DeviceImei);
                if(imageDelete == null )
                    return getResultJson(2,"请求数据有误",null);
                else if(TextUtils.isEmpty(imageDelete.deviceImei) || !imageDelete.deviceImei.equals(devImei))
                    return getResultJson(3,"IMEI 错误",null);
                else if(imageDelete.start())
                    return getResultJson(0,"操作成功",null);
                else
                    return getResultJson(4,"删除失败",null);
            }
        }else{
            return getResultJson(1,"请求类型错误",null);
        }
    }

    private String getVideoListJsonString(IHTTPSession session){
        int limit = 10;
        int offset = 0;
        int type = 0;
        Map<String, String> params = session.getParms();

        String paramLimit = params.get("limit");
        String paramOffset = params.get("offset");
        String paramType = params.get("type");

        try {
            if (!TextUtils.isEmpty(paramLimit)) {
                limit = Integer.parseInt(paramLimit);
            }
            if (!TextUtils.isEmpty(paramOffset)) {
                offset = Integer.parseInt(paramOffset);
            }
            if (!TextUtils.isEmpty(paramType)) {
                type = Integer.parseInt(paramType);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        GetVideo getVideo = VideoDBPref.getInstance().getVideoForHttp(limit,offset,type,0);

        return getResultJson(0,"",getVideo);
    }

    private String getEventListJsonString(IHTTPSession session){
//        int limit = 10;
//        int offset = 0;
//        int type = 0;
//        Map<String, String> params = session.getParms();
//
//        String paramLimit = params.get("limit");
//        String paramOffset = params.get("offset");
//        String paramType = params.get("type");
//
//        try {
//            if (!TextUtils.isEmpty(paramLimit)) {
//                limit = Integer.parseInt(paramLimit);
//            }
//            if (!TextUtils.isEmpty(paramOffset)) {
//                offset = Integer.parseInt(paramOffset);
//            }
//            if (!TextUtils.isEmpty(paramType)) {
//                type = Integer.parseInt(paramType);
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//
//        GetEvent getevent = EventDBPref.getInstance().getEventListByHttp(limit,offset,type);
        return getResultJson(1,"请使用新的接口/mapgoo.api/car_DownloadEvent",null);
    }

    private String getDeviceInfo(IHTTPSession session){
        DeviceInfo info = new DeviceInfo();
        info.videopath = MyDate.getDateTime();//"";//VideoScannerThread.mVideoDirPath;
        info.imei = QuickShPref.getInstance().getString(QuickShPref.DeviceImei);
        info.iccid = QuickShPref.getInstance().getString("");
        return getResultJson(0,"",info);
    }


    private String getstartNavi(IHTTPSession session){
        int error = 0;
        String reason = "";
        String result = "";

        Map<String, String> params = session.getParms();

        String paramPoi = params.get("content");
        String paramLat = params.get("lat");
        String paramLng = params.get("lng");

        if(TextUtils.isEmpty(paramLat)||TextUtils.isEmpty(paramLng)){
            return getResultJson(1,"无效的经纬度","");
        }else {
//            String encodeMsg = "  ";
//            if(!TextUtils.isEmpty(paramPoi)) {
//                try {
//                    encodeMsg = Base64Util.encode(paramPoi.getBytes("GBK"));
//                } catch (UnsupportedEncodingException e) {
//                    e.printStackTrace();
//                }
//                //Base64Util.encode(paramPoi.getBytes());
//            }
//
//            String msg = String.format("*MG2000CH%s,%s,%s#", paramLng, paramLat, encodeMsg);
//
//            mContext.sendBroadcast(new Intent(DataSyncServiceSDK.ACTION_START_TAKE_PERSON).putExtra("extra", msg));
            return getResultJson(0,"操作成功","");
        }
    }

    private String setWifiSsidPwd(IHTTPSession session){
        int error = 0;
        String reason = "";
        String result = "";

        Map<String, String> params = session.getParms();

        String paramImei = params.get("imei");
        String ssid = params.get("ssid");
        String password = params.get("password");

        String devImei =  QuickShPref.getInstance().getString(QuickShPref.DeviceImei);

        if(!TextUtils.isEmpty(paramImei) && paramImei.equals(devImei)) {
            if (!TextUtils.isEmpty(ssid) && !TextUtils.isEmpty(password) && password.length() >= 8) {
//                QuickShPref.getInstance().putValueObject(QuickShPref.WIFI_SSID, ssid);
//                QuickShPref.getInstance().putValueObject(QuickShPref.WIFI_PASSWORD, password);
                return getResultJson(0, "操作成功", "");
            } else {
                return getResultJson(1, "ssid和密码不能为空", "");
            }
        }else{
            return getResultJson(1,"IMEI号不匹配","null");
        }
    }

    private String setWifiRefresh(IHTTPSession session){
        int error = 0;
        String reason = "";
        String result = "";

        Map<String, String> params = session.getParms();

        String paramImei = params.get("imei");
        String devImei =  QuickShPref.getInstance().getString(QuickShPref.DeviceImei);

        if(!TextUtils.isEmpty(paramImei) && paramImei.equals(devImei)) {
            //EventBus.getDefault().post(new EventMsg(EventMsg.WIFI_REFRESH));
            return getResultJson(0, "操作成功", "null");
        }else
            return getResultJson(1,"IMEI号不匹配","null");
    }

    private String car_DownloadEvent(IHTTPSession session){
        int limit = 10;
        int offset = 0;
        int type = 0;
        Map<String, String> params = session.getParms();

        String paramLimit = params.get("limit");
        String paramOffset = params.get("offset");
        String paramType = params.get("type");

        try {
            if (!TextUtils.isEmpty(paramLimit)) {
                limit = Integer.parseInt(paramLimit);
            }
            if (!TextUtils.isEmpty(paramOffset)) {
                offset = Integer.parseInt(paramOffset);
            }
            if (!TextUtils.isEmpty(paramType)) {
                type = Integer.parseInt(paramType);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        //CarDownloadEvent getevent = EventDBPref.getInstance().getCarDownloadEventByHttp(limit,offset,type);
        return getResultJson(0,"","");
    }

    private String imageList(IHTTPSession session){
        int limit = 10;
        int offset = 0;
        Map<String, String> params = session.getParms();

        String paramLimit = params.get("limit");
        String paramOffset = params.get("offset");

        try {
            if (!TextUtils.isEmpty(paramLimit)) {
                limit = Integer.parseInt(paramLimit);
            }
            if (!TextUtils.isEmpty(paramOffset)) {
                offset = Integer.parseInt(paramOffset);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        GetImage getImage = ImageDBPref.getInstance().getImageListByHttp(limit,offset);
        return getResultJson(0,"",getImage);
    }

    private String getVideoInfo(IHTTPSession session){
        Map<String, String> params = session.getParms();

        String paramPath = params.get("path");
        if(TextUtils.isEmpty(paramPath)){
            return getResultJson(1,"地址不能为空",null);
        }

        VideoBean video = VideoDBPref.getInstance().getVideoByPath(paramPath);
        if(video!=null && new File(paramPath).exists()) {
            return getResultJson(0, "", new VideoInfo(video));
        }else{
            return getResultJson(2, "视频不存在", null);
        }
    }

    private String getResultJson(int error, String reason, Object result){
        Map<String, Object> reqBodyParams = new HashMap<String, Object>();
        reqBodyParams.put("error",error);
        reqBodyParams.put("result",result);
        reqBodyParams.put("reason",reason);

        Gson gson = new Gson();
        return  gson.toJson(reqBodyParams);
    }

    private String getCarDownloadEventJson(int error, String reason, Object result){
        Map<String, Object> reqBodyParams = new HashMap<String, Object>();
        reqBodyParams.put("error",error);
        reqBodyParams.put("eventlist",result);
        reqBodyParams.put("reason",reason);
        Gson gson = new Gson();
        return  gson.toJson(reqBodyParams);
    }

    public class Range{
        public String start;
        public String end;

        public long getStart(){
            long ret = 0;
            try {
                ret = Long.parseLong(start);
            }catch (Exception e){
                e.printStackTrace();
            }
            return ret;
        }

        public long getEnd(){
            long ret = -1;
            try {
                ret = Long.parseLong(end);
            }catch (Exception e){
                e.printStackTrace();
            }
            MyLog.D(TAG,"getEnd="+ret);
            return ret;
        }

        public long getLength(){
            long ret = getEnd()-getStart();
            MyLog.D(TAG,"getLength="+ret);
            return ret;
        }

        @Override
        public String toString() {
            return start+"-"+end;
        }
    }

    public Range getRange(String range){
        Range ret = new Range();

        if(TextUtils.isEmpty(range) == false) {
            Pattern pattern = Pattern.compile("bytes=(.*)-(.*)");// bytes=0-724967
            Matcher matcher = pattern.matcher(range);
            if (matcher.find()) {
                ret.start = matcher.group(1);
                ret.end = matcher.group(2);
            }
        }
        MyLog.D(TAG,"getRange="+ret.toString());
        return ret;
    }

}
